﻿using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace ACC.Util.Restful
{
    /// <summary>
    /// Http 工具类
    /// </summary>
    public class HttpUtil
    {
        /// <summary>  
        /// HTTP POST请求  
        /// </summary>  
        /// <param name="baseUrl">请求的URL</param>  
        /// <param name="dic">请求的参数</param>  
        /// <param name="requestEncode">请求的编码</param>  
        /// <param name="responseEncode">响应的编码</param>  
        /// <returns>响应的结果</returns>  
        public static string PostRequest(string url, ApiBaseRequest req, int timeout)
        {
            Encoding encoding = Encoding.UTF8;
            HttpWebRequest request;
            if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                request = WebRequest.Create(url) as HttpWebRequest;
                request.ProtocolVersion = HttpVersion.Version10;
            }
            else
            {
                request = WebRequest.Create(url) as HttpWebRequest;
            }

            request.Method = "POST";
            request.Accept = "text/html, application/xhtml+xml, */*";
            request.ContentType = "application/json";
            request.Timeout = timeout;
            //if (id.Length > 0)
            //{
            //    request.Headers.Add("UID", id);
            //}

            try
            {
                IsoDateTimeConverter dateConverter = new IsoDateTimeConverter();
                dateConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
                string json = JsonConvert.SerializeObject(req, Formatting.Indented, dateConverter);

                byte[] buffer = encoding.GetBytes(json);
                request.ContentLength = buffer.Length;
                request.GetRequestStream().Write(buffer, 0, buffer.Length);
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                {
                    return reader.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true; //总是接受  
        }

        /// <summary>  
        /// HTTP GET请求  
        /// </summary>  
        /// <param name="requestUrl">请求的URL</param>  
        /// <param name="requestEncode">请求的编码</param>  
        /// <param name="responseEncode">响应的编码</param>  
        /// <returns>响应的结果</returns>  
        public static string GetRequest(string requestUrl, string requestEncode, string responseEncode)
        {
            string url = requestUrl.Substring(0, requestUrl.LastIndexOf('?'));
            string queryString = requestUrl.Substring(requestUrl.LastIndexOf('?') + 1); ;
            byte[] data = Encoding.GetEncoding(requestEncode.ToUpper()).GetBytes(queryString); ;
            WebClient webClient = new WebClient();
            try
            {
                //得到返回字符流  
                byte[] responseData = webClient.UploadData(url, "GET", data);
                //解码  
                string responseString = Encoding.GetEncoding(responseEncode.ToUpper()).GetString(responseData);
                return responseString;
            }
            catch (WebException ex)
            {
                Stream stream = ex.Response.GetResponseStream();
                string m = ex.Response.Headers.ToString();
                byte[] buf = new byte[256];
                stream.Read(buf, 0, 256);
                stream.Close();
                int count = 0;
                foreach (Byte b in buf)
                {
                    if (b > 0)
                    {
                        count++;
                    }
                    else
                    {
                        break;
                    }
                }
                return ex.Message + "\r\n\r\n" + Encoding.GetEncoding(responseEncode.ToUpper()).GetString(buf, 0, count);
            }
        }

        /// <summary>
        /// http下载文件
        /// </summary>
        /// <param name="url">下载文件地址</param>
        /// <param name="path">文件存放地址，包含文件名</param>
        /// <returns></returns>
        public static bool HttpDownload(string url, string path)
        {
            string tempPath = System.IO.Path.GetDirectoryName(path) + @"\temp";
            System.IO.Directory.CreateDirectory(tempPath);  //创建临时文件目录
            string tempFile = tempPath + @"\" + System.IO.Path.GetFileName(path) + ".temp"; //临时文件
            if (System.IO.File.Exists(tempFile))
            {
                System.IO.File.Delete(tempFile);    //存在则删除
            }

            try
            {
                using (FileStream fs = new FileStream(tempFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
                {
                    // 设置参数
                    HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
                    //发送请求并获取相应回应数据
                    HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                    //直到request.GetResponse()程序才开始向目标网页发送Post请求
                    using (Stream responseStream = response.GetResponseStream())
                    {
                        //创建本地文件写入流
                        //Stream stream = new FileStream(tempFile, FileMode.Create);
                        byte[] bArr = new byte[1024];
                        int size = responseStream.Read(bArr, 0, (int)bArr.Length);
                        while (size > 0)
                        {
                            //stream.Write(bArr, 0, size);
                            fs.Write(bArr, 0, size);
                            size = responseStream.Read(bArr, 0, (int)bArr.Length);
                        }
                        //stream.Close();
                        responseStream.Close();
                    }
                    fs.Close();

                    //System.IO.File.Move(tempFile, path);
                    File.Copy(tempFile, path, true);
                    File.Delete(tempFile);
                }
                return true;
            }
            catch (Exception ex)
            {
                if (System.IO.File.Exists(tempFile))
                {
                    System.IO.File.Delete(tempFile);    //存在则删除
                }
                return false;
            }
        }
    }
}
